import { Info } from '@/appUtils/appData/lanhuTypes'
import { copyFile, IFileItem, moveFile, stats } from '@/appUtils/fs'
import { basename, dirname, join } from '@/appUtils/path'
import { keyboard, mouse } from '@/utils/keyboardAndMouse'
import {
    handleDropEnterForInfo,
    handleDropForInfo,
    updateMouseTextForSliceInfo
} from '@/views/ReplaceDesign/dropHandlers'
import { ElMessage, ElMessageBox } from 'element-plus'
import { DragDataType } from '../../DragAndDrop/DragDataTypes'
import { IVDroppableValue } from '../../DragAndDrop/vDroppable'
import { getFileExplorerInstance } from './instances'

// 把上一次的targetPath缓存下来，例如在键盘发生变化时，事件中拿不到targetPath
// 这时可以使用上一次的targetPath
let cachedTargetPath: string | undefined = undefined

/** 根据fileList，target，键盘按键更新鼠标文本 */
export const updateMouseText = async (fileList?: IFileItem[], targetPath?: string) => {
    targetPath = targetPath || cachedTargetPath
    if (!fileList || !fileList.length || !targetPath) {
        mouse.setText('')
        return
    }
    let str = `${fileList.length}项`
    // console.log(targetPath)
    const stat = await stats(targetPath)
    // 如果是多个文件被拖动，则targetPath只能是文件夹
    if (fileList.length > 1 && !stat.isDir) {
        targetPath = dirname(targetPath)
    }
    cachedTargetPath = targetPath
    // console.log(targetPath)
    // console.log(stat.isDir)
    // 多个文件或者本来就放文件夹，多个文件的targetPath都是文件夹
    if (fileList.length > 1 || stat.isDir) {
        const currentDir = dirname(fileList[0].path)
        // 如果跟当前目录一样则置空
        if (currentDir === targetPath) {
            mouse.setText(str)
            return
        }
        str = keyboard.isShiftPressed ? '移动' : '复制'
        str += `${fileList.length}项到${basename(targetPath)}`
    } else {
        // 单个文件
        // 如果是多个文件或者一样的文件则置空
        if (fileList[0].path === targetPath) {
            mouse.setText(str)
            return
        }
        str = `替换${basename(targetPath)}`
    }
    mouse.setText(str)
}

/** 放开鼠标，拖放时 */
const handleDrop = async (fileList?: IFileItem[], targetPath?: string) => {
    targetPath = targetPath || cachedTargetPath
    if (!fileList || !fileList.length || !targetPath) {
        return
    }
    const stat = await stats(targetPath)
    // 如果是多个文件被拖动，则targetPath只能是文件夹
    if (fileList.length > 1 && !stat.isDir) {
        targetPath = dirname(targetPath)
    }
    cachedTargetPath = targetPath

    // 多个文件或者本来就放文件夹，多个文件的targetPath都是文件夹
    if (fileList.length > 1 || stat.isDir) {
        const currentDir = dirname(fileList[0].path)
        // 如果跟当前目录一样则什么都不做
        if (currentDir === targetPath) {
            return
        }
        // 按住shift为移动，默认为复制
        const type = keyboard.isShiftPressed ? 'move' : 'copy'
        copyOrMoveFilesToDir(fileList, targetPath, type)
    } else {
        // 单个文件
        // 如果是多个文件或者一样的文件则什么都不做
        if (fileList[0].path === targetPath) {
            return
        }

        const confirmDialogText = `将以下文件：
<div class="bg-slate-100 rounded px-1 break-all">${fileList[0].path}</div>
覆盖到：
<div class="bg-slate-100 rounded px-1 break-all">${targetPath}</div>
操作后将无法撤销，请确认是否继续？
`

        // 替换
        const confirm = await ElMessageBox.confirm(confirmDialogText, {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            dangerouslyUseHTMLString: true
        }).catch(() => null)
        console.log(confirm, fileList[0].path, targetPath)
        if (confirm === 'confirm') {
            try {
                await copyFile(fileList[0].path, targetPath, true)
                ElMessage.success('复制成功')
            } catch (e) {
                console.log(e)
                ElMessage.error('复制文件失败')
            }
        }
    }
}

/** 复制或移动多个文件到文件夹 */
const copyOrMoveFilesToDir = async (fileList: IFileItem[], targetPath: string, type: 'copy' | 'move' = 'copy') => {
    const proms: Promise<void>[] = []
    const func = type === 'move' ? moveFile : copyFile
    for (const file of fileList) {
        if (file.isDir) {
            proms.push(func(file.path, targetPath))
        } else {
            const newTargetPath = join(targetPath, file.name)
            proms.push(func(file.path, newTargetPath))
        }
    }
    await Promise.all(proms)
    return true
}

/** 文件列表区域的拖放逻辑处理 */
export const filesVDroppable: IVDroppableValue<IFileItem[] | Info> = {
    accepts: [DragDataType.FileList, DragDataType.SliceItemInfo],
    enter: (data, target) => {
        // 如果是文件列表
        if (!target || !target.dataset.path) return
        const targetPath = target.dataset.path
        if (data.type === DragDataType.FileList) {
            const files = data.data as IFileItem[]
            if (!files.length) return
            updateMouseText(files, targetPath)
        } else if (data.type === DragDataType.SliceItemInfo) {
            handleDropEnterForInfo(data.data as Info, targetPath)
        }
    },
    leave: (data) => {
        if (data.type === DragDataType.FileList) {
            updateMouseText()
        } else if (data.type === DragDataType.SliceItemInfo) {
            updateMouseTextForSliceInfo(data.data as Info)
        }
    },
    drop: async (data, target) => {
        if (!target || !target.dataset.path) return
        const targetPath = target.dataset.path
        updateMouseText()
        if (data.type === DragDataType.FileList) {
            // 如果是文件列表
            const files = data.data as IFileItem[]
            if (!files.length) return
            await handleDrop(files, targetPath)
        } else if (data.type === DragDataType.SliceItemInfo) {
            // 如果是切片信息
            await handleDropForInfo(data.data as Info, targetPath)
        }
        const fileExplorerId = target.dataset.fileExplorerId
        if (!fileExplorerId) return
        const fileExplorerInstance = getFileExplorerInstance(fileExplorerId)
        if (!fileExplorerInstance) return
        fileExplorerInstance.highlightFile(targetPath, true)
    }
}
